
using System;
using System.Data;
using System.Linq;
using System.Linq.Dynamic;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Threading.Tasks;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;

using Abp.UI;
using Abp.AutoMapper;
using Abp.Extensions;
using Abp.Authorization;
using Abp.Domain.Repositories;
using Abp.Application.Services.Dto;
using Abp.Linq.Extensions;


using Yozeev.BusinessLogic;
using Yozeev.BusinessLogic.Dtos;
using Yozeev.BusinessLogic.DomainService;
using Yozeev.BusinessLogic.Authorization;
using Yozeev.Common;
using Yozeev.Models;
using Abp.Authorization.Users;
using Microsoft.AspNetCore.Mvc;
using Yozeev.Help;
using Abp.Runtime.Caching;

namespace Yozeev.BusinessLogic
{
    /// <summary>
    /// TicketDetail应用层服务的接口实现方法  
    ///</summary>
    [AbpAuthorize]
    public class TicketDetailAppService : YozeevAppServiceBase, ITicketDetailAppService
    {
        private readonly IRepository<TicketDetail, Guid> _entityRepository;

        private readonly ITicketDetailManager _entityManager;

        private readonly IQueryHelper _queryHelper;

		private readonly ICacheManager _cacheManager;

		/// <summary>
		/// 构造函数 
		///</summary>
		public TicketDetailAppService(
        IRepository<TicketDetail, Guid> entityRepository
        ,ITicketDetailManager entityManager
            , IQueryHelper queryHelper
			, ICacheManager cacheManager
		)
        {
            _entityRepository = entityRepository; 
             _entityManager=entityManager;
            _queryHelper = queryHelper;
			_cacheManager = cacheManager;
		}


        /// <summary>
        /// 获取TicketDetail的分页列表信息
        ///</summary>
        /// <param name="input"></param>
        /// <returns></returns>
		[HttpGet,HttpPost]
        public async Task<PagedResultDto<TicketDetailListDto>> GetPaged(GetTicketDetailsInput input)
		{

            var expression = _queryHelper.WhereExp<TicketDetail>(input.queryData);
			if (AbpUserBase.AdminUserName != GetCurrentUser().UserName)
				expression = _queryHelper.SetWhereExp<TicketDetail>(expression, GetViewTypeEnum<TicketDetail>(), await GetBranchUser());
			var query = from entity in _entityRepository.GetAll().AsNoTracking()
                        .Where(expression)
                        select new
                        {
                            entity,
                            entity.Schedule,
                            entity.ActivityDetail,
                            entity.ActivityDetail.TicketPrice,
                            entity.Customer,
                            entity.Route,
                            entity.Boat,
                            entity.ActivityDetail.Activity,
                            entity.ActivityDetail.TicketPrice.Ticket,
							entity.ActivityDetail.Activity.PayMethod,
                            entity.Branch,
                            entity.CreatorUser
                        };
            var list = new List<TicketDetailListDto>();
            query.ToList().ForEach(temp => {
                var _entity = temp.entity.MapTo<TicketDetailListDto>();
				if (temp.Schedule != null)
				{
					_entity.Schedule = temp.Schedule;
					_entity.Schedule.Route = temp.Route;
					_entity.Schedule.Boat = temp.Boat;
				}
                _entity.ActivityDetail = temp.ActivityDetail;
                _entity.ActivityDetail.TicketPrice = temp.TicketPrice;
                _entity.Customer = temp.Customer;
                _entity.Activity = temp.Activity;
                _entity.Ticket = temp.Ticket;
				_entity.Activity.PayMethod = temp.PayMethod;
				_entity.WarePositionName = L(_entity.WarePosition.ToString());
				list.Add(_entity);
            });
            var count = list.Count();
			list = list.AsQueryable().OrderBy(input.Sorting)
					.PageBy(input)
					.ToList();
			return new PagedResultDto<TicketDetailListDto>(count, list);
		}


		/// <summary>
		/// 通过指定id获取TicketDetailListDto信息
		/// </summary>
		public async Task<TicketDetailListDto> GetById(EntityDto<Guid> input)
		{
			var entity = await _entityRepository.GetAsync(input.Id);

		    return entity.MapTo<TicketDetailListDto>();
		}

		/// <summary>
		/// 获取编辑 TicketDetail
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		public async Task<GetTicketDetailForEditOutput> GetForEdit(NullableIdDto<Guid> input)
		{
			var output = new GetTicketDetailForEditOutput();
TicketDetailEditDto editDto;

			if (input.Id.HasValue)
			{
				var entity = await _entityRepository.GetAsync(input.Id.Value);

				editDto = entity.MapTo<TicketDetailEditDto>();

				//ticketDetailEditDto = ObjectMapper.Map<List<ticketDetailEditDto>>(entity);
			}
			else
			{
				editDto = new TicketDetailEditDto();
			}

			output.TicketDetail = editDto;
			return output;
		}


		/// <summary>
		/// 添加或者修改TicketDetail的公共方法
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		public async Task CreateOrUpdate(CreateOrUpdateTicketDetailInput input)
		{

			if (input.TicketDetail.Id.HasValue)
			{
				await Update(input.TicketDetail);
			}
			else
			{
				await Create(input.TicketDetail);
			}
		}


		/// <summary>
		/// 新增TicketDetail
		/// </summary>
		protected virtual async Task<TicketDetailEditDto> Create(TicketDetailEditDto input)
		{
			//TODO:新增前的逻辑判断，是否允许新增

            // var entity = ObjectMapper.Map <TicketDetail>(input);
            var entity=input.MapTo<TicketDetail>();
			

			entity = await _entityRepository.InsertAsync(entity);
			return entity.MapTo<TicketDetailEditDto>();
		}

		/// <summary>
		/// 编辑TicketDetail
		/// </summary>
		protected virtual async Task Update(TicketDetailEditDto input)
		{
			//TODO:更新前的逻辑判断，是否允许更新

			var entity = await _entityRepository.GetAsync(input.Id.Value);
			input.MapTo(entity);

			// ObjectMapper.Map(input, entity);
		    await _entityRepository.UpdateAsync(entity);
		}



		/// <summary>
		/// 删除TicketDetail信息的方法
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		public async Task Delete(EntityDto<Guid> input)
		{
			//TODO:删除前的逻辑判断，是否允许删除
			await _entityRepository.DeleteAsync(input.Id);
		}



		/// <summary>
		/// 批量删除TicketDetail的方法
		/// </summary>
		public async Task BatchDelete(List<Guid> input)
		{
			// TODO:批量删除前的逻辑判断，是否允许删除
			await _entityRepository.DeleteAsync(s => input.Contains(s.Id));
		}


        /// <summary>
        /// 导出TicketDetail为excel表,等待开发。
        /// </summary>
        /// <returns></returns>
        //public async Task<FileDto> GetToExcel()
        //{
        //	var users = await UserManager.Users.ToListAsync();
        //	var userListDtos = ObjectMapper.Map<List<UserListDto>>(users);
        //	await FillRoleNames(userListDtos);
        //	return _userListExcelExporter.ExportToFile(userListDtos);
        //}

        /// <summary>
        /// 打印票据
        /// </summary>
        /// <param name="ticketDetailId">票据Id列表</param>
        /// <returns></returns>
        public async Task<ActivityResultModel> PrintTicketDetail(List<Guid> ticketDetailIds)
        {
			ActivityResultModel activityResultModel = new ActivityResultModel()
			{
				ResultCode = "000",
				ResultMessage = "打印成功",
			};
			try
			{
				foreach (var id in ticketDetailIds)
				{
					var entity = await _entityRepository.GetAsync(id);
					if (entity.TicketStatus == Abp.Domain.Entities.Auditing.TicketStatusEnum.TicketRefund)
						throw new Exception("存在已退款的票");
					if (entity.TicketStatus == Abp.Domain.Entities.Auditing.TicketStatusEnum.Used)
						throw new Exception("存在已使用的票");
					//if (entity.IsPrint )
					//    throw new Exception("存在已打印的票");
					entity.IsPrint = true;
					await _entityRepository.UpdateAsync(entity);
				}
			}
			catch (Exception ex)
			{
				return new ActivityResultModel()
				{
					ResultCode = "001",
					ResultMessage = ex.Message,
					Detail = ex.StackTrace,
				};
			}
			return activityResultModel;
		}

		/// <summary>
		/// 生成或获取取票码
		/// </summary>
		/// <param name="TickeDetailId"></param>
		/// <returns></returns>
		public async  Task<string> GetCollectionCode(Guid TickeDetailId)
		{
			var entity = await _entityRepository.GetAsync(TickeDetailId);
			if (entity == null)
				throw new UserFriendlyException("查无该票据Id");
			if(entity.CollectionCode.IsNullOrWhiteSpace())
			{
				//生成取票码
				entity.CollectionCode = CommonHelp.getVoucherNo();
				await _entityRepository.UpdateAsync(entity);
			}
			//添加到缓存中
			var cacheKey = CacheConsts.Portal_Wiki;
			var cache = _cacheManager.GetCache(cacheKey);
			cache.DefaultAbsoluteExpireTime = TimeSpan.FromMinutes(5);
			await cache.SetAsync(TickeDetailId.ToString(), entity.CollectionCode);
			return entity.CollectionCode;
		}

	}
}


